import 'package:jd_flutter/base/utils/jd_log.dart';

class DartBasic {
  helloDemo() => print('hello');

  forEachDemo(List list, void func(var element)) {
    for (var e in list) {
      func(e);
    }
  }

  int b = 0;
  printElement(var a) {
    b++;
    print('元素$b = $a');
  }

  test3() {
    int? a;
    // 如果 a 没有值，就进行赋值，如果 a 有值就不会赋值
    a ??= 10;

    var b;
    // 如果左边有值就打印左边，如果左边没值就打印右边
    print(a ?? b);

    // 正常写法
    int sum(int a, int b) {
      return a + b;
    }

// 省略参数跟返回值
    sum1(a, b) {
      return a + b;
    }

// 使用箭头函数 => 表达式
    sum2(a, b) => a + b;
  }

  mapTest() {
    // 不可变 map
    var map1 = const {'key1': 'one', 'key2': 'two'};

    // 可变 map
    var map2 = {'key1': 'one', 'key2': 'two'};
    // 获取 key 对应的值
    print(map2['key1']);
    // 修改 key 对应的值
    map2['key1'] = 'hello';
    // 打印 map 的长度
    print(map2.length);
    // 获取 map 中所有的 value
    print(map2.values);
    // 获取 map 中所有的 key
    print(map2.keys);

    // 将 list 转为 map，结果就是 {0: one, 1: two, 2: three}
    var list = ['one', 'two', 'three'];
    var map3 = list.asMap();
  }

  listTest() {
    // 不可变 list，数据先去加 const 修饰
    var list = const ['one', 'two', 'three', 1];

    // 可变 list
    var list1 = ['one', 'two', 'three', 1];
    // 根据下标打印元素
    print(list1[1]);
    // 修改下标为 1 的元素
    list1[1] = 3;
    // 打印 list 元素数量
    print(list1.length);
    // 追加一个元素
    list1.add(5);
    // 在 下边为 1 的位置插入一个元素
    list1.insert(1, '33');
    // 删除某个元素
    list1.remove('one');
    // 清空 list
    list1.clear();

    var list2 = [1, 3, 2];
    // 对 list 进行排序，得到的结果就是 [1, 2, 3]
    list2.sort();
    // 获取 list 下标 1 到 3 之间的元素
    list2.sublist(1, 3);
    // 取数组前2个,不够2个有几个取几个
    list2.take(2);
  }

  stringTest() {
    // 用单引号或者双引号修饰都可以
    var a = 'hello';
    var b = "world";
    String c = a + b;

    // 用 3 个引号修饰，字符串可以换行
    String d = '''hello
  world''';

    // 获取字符串 a 中的第 0 个字符跟第 1 个字符，这里可以看到会非常方法，可以用下标的方式去取
    print(a[0]);
    print(a[1]);

    String e = a * 2; // 这个结果等于 hellohello，就是把 a 的值再复制一份

    int f = 10;
    int g = 20;
    int h = f + g;
    print('a + b = ${a + b}'); // 输出结果为 a + b = 30，在字符串里面拼接运算表达式
    print('a + b = $h'); // 这个结果跟上面输出结果是一样的

    String str = "hello\nworld";
    print(str); // 这个输出的结果就是 hello 换行之后是 world

    String str1 = r"hello\nworld";
    print(str1); // 这个输出的结果就是 hello\nworld, \n 没起作用

    print(str1.length); // 打印字符串长度
  }

  numTest() {
    /*
    Dart 的数据类型之 num
数值型 num 分为两种 int 跟 double。
num 类型的变量如果被使用的话必须要有值，
   */
    int a = 10;
    print(a.isEven); // 判断是否是偶数
    print(a.isOdd); // 判断是否是奇数

    // 运算符 + - * / % (取模)  ~/ (取整数)
    int b = a + 10;
    int c = a - 5;
    int d = a * 3;
    double e = a / 2;
    int f = a % 6;
    int g = a ~/ 8; // 这个结果为 1，相当于 a 除 8 的结果取整

    // 转换类型
    int h = 10.3.toInt(); // double 类型转换为 int
    double i = 5.toDouble(); // int 类型转换为 double
  }

  test2() {
    /*
  使用 final 声明的变量只能被赋值一次，再次赋值的话会报错，它是最终变量。
  使用 final 声明的变量在使用前必须有值，不然也会报错。
   */
    final int c;
    // jdLog(c);
    c = 1;
/*
   const 关键字
     使用 const 声明的常量初始化的时候必须被赋值。
  使用 const 声明的常量不能被修改。
 */
    const d = 10;
  }

  test1() {
    String testString = 'testString';
    var a = '1';
    jdLog('$a $testString');
    a = 'hello world';
    jdLog(a);

    int b = 10;
    jdLog(b);
  }

  sum(a, {b, c}) {
    b ??= 0;
    c ??= 0;
    return a - b + c;
  }

// 参数如果为 int 型，就需要用 int？修饰，告诉编译器参数可以为空
  sum1(a, {int? b, int? c}) {
    b ??= 0;
    c ??= 0;
    return a - b + c;
  }

// 也可以给参数一个默认值
  sum2(a, {int b = 0, int c = 0}) {
    return a - b + c;
  }

// 用 [] 修饰可选参数调用的时候可以不用带参数名称，但是必须按参数的顺序传值
  sum3(a, [int b = 0, int c = 0]) {
    return a - b + c;
  }
}
